{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Python自动生成PDF文件\n",
    "\n",
    "使用类库：reportlab (https://www.reportlab.com/)  \n",
    "安装方法：pip install reportlab\n",
    "\n",
    "实现步骤：\n",
    "1. 引入相关包\n",
    "2. 添加标题文字\n",
    "3. 添加正文文字\n",
    "4. 添加表格(借助pandas读取excel生成表格)\n",
    "5. 添加图片(借助matplotlib绘图生成图片)\n",
    "6. 生成PDF文件"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1. 引入相关包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Collecting reportlab\n",
      "  Downloading reportlab-3.6.9-cp39-cp39-win_amd64.whl (2.3 MB)\n",
      "Requirement already satisfied: pillow>=4.0.0 in c:\\anaconda3\\lib\\site-packages (from reportlab) (8.4.0)\n",
      "Installing collected packages: reportlab\n",
      "Successfully installed reportlab-3.6.9\n"
     ]
    }
   ],
   "source": [
    "!pip install reportlab"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "from reportlab.pdfbase import pdfmetrics\n",
    "from reportlab.pdfbase.ttfonts import TTFont\n",
    "from reportlab.lib.styles import getSampleStyleSheet,ParagraphStyle\n",
    "from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer,Image,Table,TableStyle\n",
    "from reportlab.lib.enums import TA_CENTER,TA_LEFT,TA_JUSTIFY\n",
    "from reportlab.lib import colors\n",
    "from reportlab.lib.pagesizes import A4\n",
    "from reportlab.lib.units import inch"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "### 设置中文字体名称为微软雅黑，msyh.ttf需要自己指定文件路径\n",
    "pdfmetrics.registerFont(TTFont('msyh', 'msyh.ttf'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 容纳所有的PDF的内容\n",
    "elements = []"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. 添加标题文字"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 读取reportlab定义好的样式表\n",
    "style = getSampleStyleSheet()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 可以用两个问号，查看有多少种现成的样式\n",
    "getSampleStyleSheet??"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "title = \"\"\" <para> <font face=\"msyh\"> 北京2019年天气数据 </font> </para>\"\"\"\n",
    "elements.append(Paragraph(title, style['Title']))\n",
    "elements.append(Spacer(1, 0.2*inch))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. 添加正文文字"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "description = \"\"\"\n",
    "        <para>\n",
    "            <font face=\"msyh\">\n",
    "                下文展示了2019年北京天气数据按月表格、以及按月平均温度对比图\n",
    "            </font>\n",
    "        </para>\"\"\"\n",
    "elements.append(Paragraph(description, style[\"BodyText\"]))\n",
    "elements.append(Spacer(1, 0.2*inch))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4. 添加表格"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.read_csv(\"./beijing_tianqi_2019.csv\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ymd</th>\n",
       "      <th>bWendu</th>\n",
       "      <th>yWendu</th>\n",
       "      <th>tianqi</th>\n",
       "      <th>fengxiang</th>\n",
       "      <th>fengli</th>\n",
       "      <th>aqi</th>\n",
       "      <th>aqiInfo</th>\n",
       "      <th>aqiLevel</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>2019-01-01</td>\n",
       "      <td>1℃</td>\n",
       "      <td>-10℃</td>\n",
       "      <td>晴~多云</td>\n",
       "      <td>西北风</td>\n",
       "      <td>1级</td>\n",
       "      <td>56</td>\n",
       "      <td>良</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2019-01-02</td>\n",
       "      <td>1℃</td>\n",
       "      <td>-9℃</td>\n",
       "      <td>多云</td>\n",
       "      <td>东北风</td>\n",
       "      <td>1级</td>\n",
       "      <td>60</td>\n",
       "      <td>良</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2019-01-03</td>\n",
       "      <td>2℃</td>\n",
       "      <td>-7℃</td>\n",
       "      <td>霾</td>\n",
       "      <td>东北风</td>\n",
       "      <td>1级</td>\n",
       "      <td>165</td>\n",
       "      <td>中度污染</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2019-01-04</td>\n",
       "      <td>2℃</td>\n",
       "      <td>-7℃</td>\n",
       "      <td>晴</td>\n",
       "      <td>西北风</td>\n",
       "      <td>2级</td>\n",
       "      <td>50</td>\n",
       "      <td>优</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>2019-01-05</td>\n",
       "      <td>0℃</td>\n",
       "      <td>-8℃</td>\n",
       "      <td>多云</td>\n",
       "      <td>东北风</td>\n",
       "      <td>2级</td>\n",
       "      <td>29</td>\n",
       "      <td>优</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          ymd bWendu yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel\n",
       "0  2019-01-01     1℃   -10℃   晴~多云       西北风     1级   56       良         2\n",
       "1  2019-01-02     1℃    -9℃     多云       东北风     1级   60       良         2\n",
       "2  2019-01-03     2℃    -7℃      霾       东北风     1级  165    中度污染         4\n",
       "3  2019-01-04     2℃    -7℃      晴       西北风     2级   50       优         1\n",
       "4  2019-01-05     0℃    -8℃     多云       东北风     2级   29       优         1"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 把bWendu温度列从字符串变成数字\n",
    "df[\"bWendu\"] = df[\"bWendu\"].str.replace(\"℃\", \"\").astype(int)\n",
    "# 添加月份数字列\n",
    "df[\"month\"] = pd.to_datetime(df[\"ymd\"]).dt.month"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ymd</th>\n",
       "      <th>month</th>\n",
       "      <th>bWendu</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>2019-01-01</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2019-01-02</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2019-01-03</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2019-01-04</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>2019-01-05</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          ymd  month  bWendu\n",
       "0  2019-01-01      1       1\n",
       "1  2019-01-02      1       1\n",
       "2  2019-01-03      1       2\n",
       "3  2019-01-04      1       2\n",
       "4  2019-01-05      1       0"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df[[\"ymd\", \"month\", \"bWendu\"]].head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "table = df.groupby(\"month\")[\"bWendu\"].agg(mean=np.mean, max=np.max, min=np.min).reset_index()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>month</th>\n",
       "      <th>mean</th>\n",
       "      <th>max</th>\n",
       "      <th>min</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>4.161290</td>\n",
       "      <td>10</td>\n",
       "      <td>-2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>5.250000</td>\n",
       "      <td>14</td>\n",
       "      <td>-3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>15.741935</td>\n",
       "      <td>25</td>\n",
       "      <td>11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>20.900000</td>\n",
       "      <td>28</td>\n",
       "      <td>9</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>29.322581</td>\n",
       "      <td>37</td>\n",
       "      <td>23</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>6</td>\n",
       "      <td>32.233333</td>\n",
       "      <td>36</td>\n",
       "      <td>25</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>7</td>\n",
       "      <td>32.935484</td>\n",
       "      <td>38</td>\n",
       "      <td>26</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>8</td>\n",
       "      <td>30.387097</td>\n",
       "      <td>33</td>\n",
       "      <td>27</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>9</td>\n",
       "      <td>29.333333</td>\n",
       "      <td>35</td>\n",
       "      <td>24</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>10</td>\n",
       "      <td>19.225806</td>\n",
       "      <td>30</td>\n",
       "      <td>12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>11</td>\n",
       "      <td>10.366667</td>\n",
       "      <td>18</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>12</td>\n",
       "      <td>3.870968</td>\n",
       "      <td>10</td>\n",
       "      <td>-5</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    month       mean  max  min\n",
       "0       1   4.161290   10   -2\n",
       "1       2   5.250000   14   -3\n",
       "2       3  15.741935   25   11\n",
       "3       4  20.900000   28    9\n",
       "4       5  29.322581   37   23\n",
       "5       6  32.233333   36   25\n",
       "6       7  32.935484   38   26\n",
       "7       8  30.387097   33   27\n",
       "8       9  29.333333   35   24\n",
       "9      10  19.225806   30   12\n",
       "10     11  10.366667   18    3\n",
       "11     12   3.870968   10   -5"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "table"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>month</th>\n",
       "      <th>mean</th>\n",
       "      <th>max</th>\n",
       "      <th>min</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1月</td>\n",
       "      <td>4.16</td>\n",
       "      <td>10</td>\n",
       "      <td>-2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2月</td>\n",
       "      <td>5.25</td>\n",
       "      <td>14</td>\n",
       "      <td>-3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3月</td>\n",
       "      <td>15.74</td>\n",
       "      <td>25</td>\n",
       "      <td>11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4月</td>\n",
       "      <td>20.90</td>\n",
       "      <td>28</td>\n",
       "      <td>9</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5月</td>\n",
       "      <td>29.32</td>\n",
       "      <td>37</td>\n",
       "      <td>23</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>6月</td>\n",
       "      <td>32.23</td>\n",
       "      <td>36</td>\n",
       "      <td>25</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>7月</td>\n",
       "      <td>32.94</td>\n",
       "      <td>38</td>\n",
       "      <td>26</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>8月</td>\n",
       "      <td>30.39</td>\n",
       "      <td>33</td>\n",
       "      <td>27</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>9月</td>\n",
       "      <td>29.33</td>\n",
       "      <td>35</td>\n",
       "      <td>24</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>10月</td>\n",
       "      <td>19.23</td>\n",
       "      <td>30</td>\n",
       "      <td>12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>11月</td>\n",
       "      <td>10.37</td>\n",
       "      <td>18</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>12月</td>\n",
       "      <td>3.87</td>\n",
       "      <td>10</td>\n",
       "      <td>-5</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   month   mean  max  min\n",
       "0     1月   4.16   10   -2\n",
       "1     2月   5.25   14   -3\n",
       "2     3月  15.74   25   11\n",
       "3     4月  20.90   28    9\n",
       "4     5月  29.32   37   23\n",
       "5     6月  32.23   36   25\n",
       "6     7月  32.94   38   26\n",
       "7     8月  30.39   33   27\n",
       "8     9月  29.33   35   24\n",
       "9    10月  19.23   30   12\n",
       "10   11月  10.37   18    3\n",
       "11   12月   3.87   10   -5"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 平均值保留2位小数\n",
    "table[\"mean\"] = table[\"mean\"].map(lambda x:round(x,2))\n",
    "table[\"month\"] = table[\"month\"].map(lambda x: f\"{x}月\")\n",
    "table"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 变成[(1,1,1), (2,2,2)]的形式\n",
    "table_data  = table.to_numpy().tolist()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "table_data = [[\"月份\", \"平均温度\", \"最高温度\", \"最低温度\"]] + table_data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[['月份', '平均温度', '最高温度', '最低温度'],\n",
       " ['1月', 4.16, 10, -2],\n",
       " ['2月', 5.25, 14, -3],\n",
       " ['3月', 15.74, 25, 11],\n",
       " ['4月', 20.9, 28, 9],\n",
       " ['5月', 29.32, 37, 23],\n",
       " ['6月', 32.23, 36, 25],\n",
       " ['7月', 32.94, 38, 26],\n",
       " ['8月', 30.39, 33, 27],\n",
       " ['9月', 29.33, 35, 24],\n",
       " ['10月', 19.23, 30, 12],\n",
       " ['11月', 10.37, 18, 3],\n",
       " ['12月', 3.87, 10, -5]]"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "table_data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 添加一个小标题\n",
    "elements.append(Paragraph(\"\"\"<para><font face=\"msyh\">按月温度数据：</font></para>\"\"\", style[\"h3\"]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 表格样式\n",
    "table_styles = [\n",
    "    ('GRID', (0,0), (-1,-1), 1, colors.black),\n",
    "    ('FONTSIZE', (0,0), (-1,-1), 12),\n",
    "    ('ALIGN', (0,-1), (-1,-1), 'LEFT'),\n",
    "    ('FONT', (0,0), (-1,-1), 'msyh')\n",
    "]\n",
    "\n",
    "# 表格对象\n",
    "mytable = Table(table_data)\n",
    "mytab_style = TableStyle(table_styles)\n",
    "mytable.setStyle(mytab_style)\n",
    "\n",
    "# 添加对象\n",
    "elements.append(mytable)\n",
    "elements.append(Spacer(1, 0.2*inch))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 5. 添加图片"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig = plt.figure()\n",
    "# 画一个柱状图\n",
    "plt.bar(table.index, table[\"mean\"])\n",
    "fig.savefig('plot.png')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 添加一个小标题\n",
    "elements.append(Paragraph(\"\"\"<para><font face=\"msyh\">按月平均温度对比图：</font></para>\"\"\", style[\"h3\"]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 添加图片\n",
    "img = Image('plot.png')\n",
    "elements.append(img)\n",
    "elements.append(Spacer(1, 0.2*inch))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 6. 生成PDF文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [],
   "source": [
    "doc = SimpleDocTemplate(\n",
    "    \"2019年北京天气数据.pdf\", \n",
    "    pagesize=(A4[0], A4[1]),\n",
    "    topMargin = 30,\n",
    "    bottomMargin = 30)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "doc.build(elements)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
